/**
 * IndexSearch.java	1.0 2007 五月 30 16:01:15,创建
 */

package org.in4j.search;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.lucene.document.Document;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.Hits;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.MultiSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.Searcher;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.in4j.core.dao.support.Pagination;
import org.in4j.search.index.IndexSource;

/**
 *
 * @author 杨帆
 * @version 1.0 2007 五月 30 16:01:15,创建
 */
public class IndexSearch
{
	@SuppressWarnings("unused")
	private static final Log log = LogFactory.getLog(IndexSearch.class);

	private IndexSource[] indexSources;

	private String[] searchRange;

	public IndexSearch(String... searchRange)
	{
		this.searchRange = searchRange;
	}

	public void setConfig(SearchConfig searchConfig)
	{
		indexSources = searchConfig.getIndexSources();
	}

	public Pagination<Map<String, String>> searchForPagination(Query query,int pageNo,int pageSize)
	{

		final List<Map<String,String>> list = new ArrayList<Map<String,String>>();
		long st = System.currentTimeMillis();

		int recordCount = 0;
		Hits hits = null;
		try
		{
			Searcher searcher = getIndexSearcher();
			hits = searcher.search(query);
			recordCount = hits.length();

			final Pagination<Map<String, String>> pagination = new Pagination<Map<String,String>>(list,recordCount,pageSize);

			int maxResult = Math.min(pageSize, recordCount);

			for(int i = pagination.getStartIndex(); i < maxResult; i++)
			{
				Document doc = hits.doc(i);
				String fieldsString = doc.get("fields");
				if(log.isDebugEnabled() && i == pagination.getStartIndex())
					log.debug("fields:\n" + fieldsString);
				String[] fields = getFields(fieldsString);
				Map<String, String> map = new HashMap<String, String>();
				for(String field: fields)
				{
					String value = doc.get(field);
					map.put(field, value);
				}
				list.add(map);
			}
		}
		catch(IOException e)
		{
			e.printStackTrace();
		}

		long et = System.currentTimeMillis();
		double time = (double)(et - st) / 1000;

		final Pagination<Map<String, String>> result = new Pagination<Map<String,String>>(list,recordCount,pageSize);

		System.out.println("搜索结束,共搜索到" + recordCount + "条结果,用时:" + time + "秒");

		return result;
	}

	private String[] getFields(String fieldsString)
	{
		return fieldsString.split(",");
	}

	private Searcher getIndexSearcher() throws IOException
	{
		List<IndexSearcher> searchers = new ArrayList<IndexSearcher>();
		for(String range: searchRange)
		{
			String module = getModule(range);
			String table = getTable(range);
			IndexSource source = getIndexSource(module);
			Directory dir = FSDirectory.getDirectory(source.getIndexDirForTable(table),false);
			IndexSearcher indexSearcher = new IndexSearcher(dir);
			searchers.add(indexSearcher);
		}

		MultiSearcher multiSearcher = new MultiSearcher(searchers.toArray(new IndexSearcher[0]));
		return multiSearcher;
	}

	private IndexSource getIndexSource(String moduleId)
	{
		for(IndexSource source: indexSources)
		{
//			log.debug("current source:" + source);
			if(moduleId.equals(source.getId()))
				return source;
		}
		throw new IllegalStateException("找不到模块 " + moduleId + " 所对应的配置.");
	}

	private String getTable(String range)
	{
		return StringUtils.substringAfter(range, ".");
	}

	private String getModule(String range)
	{
		String module = StringUtils.substringBefore(range, ".");
		return module;
	}




}
